﻿package test {
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.text.TextFormat;

	/**
	 * ...
	 * @author Marcelo Volmaro
	 */
	[Frame(factoryClass = "extremefx.Preloader")];
	public class ArabicConverter extends Sprite {
		//define letters that can connect from the left
		private static var _left:String = "ـئظشسيبلتنمكطضصثقفغعهخحج";
		
		//define letters that can connect from the right
		private static var _right:String = "ـئؤرلالآىآةوزظشسيبللأاأتنمكطضصثقفغعهخحجدذلإإ";
		
		//define all arabic letters + harakat + arabic symbols	
		private static var _notEng:String = "ًٌٍَُِّْْئءؤرلاىةوزظشسيبلاتنمكطضصثقفغعهخحجدذْلآآلأأـلإإ،؟";
		
		//define the harakat
		private static var _harakat:String = "ًٌٍَُِّْْ";
		
		//define other symbols
		private static var _symbols:String = "ًٌٍَُِّـ.،؟ @#$%^&*-+|\/=~ْ,:";
		
		//define arabic unicode chars
		private static var _unicode:String = "ﺁﺁﺂﺂﺃﺃﺄﺄﺇﺇﺈﺈﺍﺍﺎﺎﺏﺑﺒﺐﺕﺗﺘﺖﺙﺛﺜﺚﺝﺟﺠﺞﺡﺣﺤﺢﺥﺧﺨﺦﺩﺩﺪﺪﺫﺫﺬﺬﺭﺭﺮﺮﺯﺯﺰﺰﺱﺳﺴﺲﺵﺷﺸﺶﺹﺻﺼﺺﺽﺿﻀﺾﻁﻃﻄﻂﻅﻇﻈﻆﻉﻋﻌﻊﻍﻏﻐﻎﻑﻓﻔﻒﻕﻗﻘﻖﻙﻛﻜﻚﻝﻟﻠﻞﻡﻣﻤﻢﻥﻧﻨﻦﻩﻫﻬﻪﻭﻭﻮﻮﻱﻳﻴﻲﺓﺓﺔﺔﺅﺅﺆﺆﺉﺋﺌﺊﻯﻯﻰﻰﻵﻵﻶﻶﻷﻷﻸﻸﻹﻹﻺﻺﻻﻻﻼﻼ";

		private static var _arabic:String = "آأإابتثجحخدذرزسشصضطظعغفقكلمنهويةؤئى";
		private static var _newla:String = "ﻵﻵﻶﻶﻷﻷﻸﻸﻹﻹﻺﻺﻻﻻﻼﻼ";

		private static var _arnumbs:Array = ["٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩"];
		
		private static var _ennumbs:String = "0123456789";
		private static var _brackets:String = "(){}[]";

		private var _out:Array;
		
		public var UseArabicNumbers:Boolean;

		
		public function ArabicConverter() {
			UseArabicNumbers = false;
		}
		
		public function convert(pInput:String):String {
			pInput = pInput.split("\r\n").join("\n");
			var x:Array = pInput.split("");
			var len:Number = x.length;
			
			_out = [];
			
			//Should I replace English numbers with Arabic ones?
			var g:Number;
			
			if (UseArabicNumbers) {
				for (g = 0; g < len; g++) {
					var numpos:Number = _ennumbs.indexOf(x[g]);
					if (numpos >= 0) {
						x[g] = _arnumbs[numpos];
					}
				}
			}
			
			//process each letter, submit it to tests and then add it to the output string
			for (g = 0; g < len; g++) {
				var a:Number, b:Number;
				a = b = 1;
				
				//ignoring the harakat
				while (_harakat.indexOf(x[g - b]) >= 0) b++;
				while (_harakat.indexOf(x[g + a]) >= 0) a++;
				
				//determine the position of each letter
				var pos:Number;
				if (g == 0) {
					pos = (_right.indexOf(x[a]) >= 0) ? 1 : 0;
					
				} else if (g == (len - 1)) {
					pos = (_left.indexOf(x[len - b - 1]) >= 0) ? 3 : 0;
					
				} else {
					if (_left.indexOf(x[(g - b)]) < 0) {
						pos = (_right.indexOf(x[(g + a)]) < 0) ? 0 : 1;
						
					} else if (_left.indexOf(x[(g - b)]) >= 0) {
						pos = (_right.indexOf(x[(g + a)]) >= 0) ? 2 : 3;
					}
				}
				
				var char:String = x[g];
				
				if (char == "\n") {
					_out.unshift("\n");
					
				} else if (_brackets.indexOf(char) >= 0) {
					
					//if this char is a bracket, reverse it
					var temp:Number = _brackets.indexOf(char);
					_out.unshift((temp % 2 == 0) ? _brackets.charAt(temp + 1) : _brackets.charAt(temp - 1));
					
				} else if (char == "ء") {
					_out.unshift("ﺀ");
					
				} else if (_arabic.indexOf(char)>=0) {
					//if the char is an Arabic letter..
					if (char=="ل")	{
						//if this letter is (laam)
						//check if its actually a (laa) combination
						var ar_pos:Number = _arabic.indexOf(x[g + 1]);
						
						if ((ar_pos >= 0) && (ar_pos < 4)) {
							_out.unshift(_newla.charAt((ar_pos * 4) + pos));
							g++;
							
						} else {
							//if its just (laam)
							_out.unshift("ل");
						}
						
					} else	{
						//if its any arabic letter other than (laam)
						_out.unshift(_unicode.charAt((_arabic.indexOf(char)*4)+pos));
					}
					
				} else if (_symbols.indexOf(char) >= 0) {
					//if the char is a symbol, add it
					_out.unshift(char);	
					
				} else {
					//if the char is none of the above, then treat it as english text (don't reverse)
					//since i'm outputting the text in reverse order, i have to store the english text reversed
					//so it is displays correctly after it has been re-reversed :)
					
					var enText:Array = [];
					var h:Number = g;
					
					while (true) {
						if (h >= len) break;
						
						var currentChar:String = x[h];
						if (_notEng.indexOf(currentChar) > 0) break;
						if (_unicode.indexOf(currentChar) > 0) break;
						
						enText.push(currentChar);
						h++;
						
						//sentences end at new line. This works in the same way as the Unicode Algorithm
						if (currentChar == "\n") break;
					}
					
					var r:Number = enText.length - 1;
					
					if (r < 1) {
						g = h;
						
					} else {
						//make sure spaces between arabic and english text display properly
						if (r == 1 && enText[1] == " ") {
							//reverse the space position
							enText.unshift(enText.pop());
							
						} else {
							while (enText[r] == " ") {
								enText.unshift(enText.pop());
							}
						}
						
						//copy english text
						r = enText.length;
						while (r) {
							_out.unshift(enText[--r]);
						}
						
						//set the loop pointer to the first char after the english text.
						g = h - 1;	
					}
				}
			}
			
			return _out.join("");
		}
		
		private var _tf:TextField;
		
		public function main():void {
			var tf:TextField = _tf = new TextField();
			tf.defaultTextFormat = new TextFormat("arial unicode ms", 14, 0);
			
			addChild(tf);
			tf.x = 0;
			tf.y = 0;
			tf.width = stage.stageWidth;
			tf.height = stage.stageHeight;
			tf.border = true;

			var text:String = "يعمل Montana World Trade Center‏ (MWTC) لزيادة وتعليم الطلبة.";
			
			tf.appendText(text);
			tf.appendText("\n");
			tf.appendText(convert(text));
		}
	}
}